package cn.doitedu.server;


import cn.doitedu.core.DataManagerService;
import cn.doitedu.core.StudentBean;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
public class MyProtocolServer {

    public static void main(String[] args) throws Exception {

        int serverPort = 0;
        String dataFilePath="";
        String metaFilePath="";
        try{
            serverPort = Integer.parseInt(args[0]);
            dataFilePath = args[1];
            metaFilePath = args[2];
        }catch (Exception e){

            System.out.println("正确启动服务，需要传入以下参数：");
            System.out.println("1.端口号[整数]");
            System.out.println("2.数据文件的路径");
            System.out.println("3.元数据文件的路径");
            System.exit(1);
        }


        // 注册监听端口
        ServerSocket serverSocket = new ServerSocket(serverPort);
        log.info("成功注册端口:{}", serverPort);

        // 实例化核心功能类
        DataManagerService dataManagerService = new DataManagerService(dataFilePath,metaFilePath);


        while (true) {
            // 等待客户端请求
            // accept()是一个阻塞方法：如果没有客户端请求，则不会return
            Socket socket = serverSocket.accept();
            log.info("成功建立与客户端的连接");

            // 有了socket连接，就可以利用它来跟客户端进行通信
            // 从连接对象上获取一个 输出流： 用于向客户端输出信息
            OutputStream outputStream = socket.getOutputStream();

            // 从连接对象上获取一个 输入流： 用于从客户端接收信息
            InputStream inputStream = socket.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));


            /**
             * 接收客户端的 功能需求 ：
             *     MD5:QUERY:FIND_BY_ID:3
             *     MD5:QUERY:FIND_BY_NAME:王瑛
             *     MD5:QUERY:FIND_BY_WORD:咖啡
             *     MD5:ADD:1,张三,18,
             *
             * 然后帮客户端，去调用本地的核心api
             *
             * 然后将结果发送给客户端
             */

            // 1. 接收客户端的请求信息
            String request = bufferedReader.readLine();
            log.info("收到客户端请求 => {}",request);

            // 2. 解析请求信息，并验证MD5是否正确
            String[] arr = request.split(":", 2);
            String md5 = DigestUtils.md5Hex(arr[1]);
            if (!md5.equals(arr[0])) {
                log.error("md5码验证失败,收到的md5:{},本地md5:{}",arr[0],md5);
                outputStream.write("ERROR \n".getBytes());
            }

            // 3. 根据请求的意图，调用DataManagerService的对应方法获取结果
            String[] arr2 = arr[1].split(":");
            if (arr2[0].equals("QUERY")) {
                if (arr2[1].equals("FIND_BY_ID")) {
                    String queryId = arr2[2];
                    // 调用核心功能的方法
                    String studentInfo = dataManagerService.findStudentById(Integer.parseInt(queryId));
                    // 将查询出来的原始字符串结果，转成javaBean，再转成json字符串
                    String[] fields = studentInfo.split(",");
                    StudentBean studentBean = new StudentBean(Integer.parseInt(fields[0]), fields[1], Integer.parseInt(fields[2]), fields[3], fields[4], fields[5]);
                    String jsonString = JSON.toJSONString(studentBean);

                    // 将结果发给客户端
                    outputStream.write((jsonString + "\n").getBytes());
                } else if (arr2[1].equals("FIND_BY_NAME")) {
                    String queryName = arr2[2];
                    // 调用核心功能的方法
                    List<String> studentsByName = dataManagerService.findStudentsByName(queryName);

                    // 将查询出来的原始字符串结果，转成javaBean，再转成json字符串
                    List<StudentBean> beanList = studentsByName.stream().map(line -> {
                        String[] fields = line.split(",");
                        return new StudentBean(Integer.parseInt(fields[0]), fields[1], Integer.parseInt(fields[2]), fields[3], fields[4], fields[5]);
                    }).collect(Collectors.toList());


                    String jsonString = JSON.toJSONString(beanList);

                    // 将结果发给客户端
                    outputStream.write((jsonString + "\n").getBytes());
                } else if (arr2[1].equals("FIND_BY_WORD")) {
                    String queryWord = arr2[2];
                    log.info("准备按兴趣词查询数据，兴趣词为： {}",queryWord);
                    // 调用核心功能的方法
                    List<String> studentsByName = dataManagerService.findStudentsByInterestWord(queryWord);

                    // 将查询出来的原始字符串结果，转成javaBean，再转成json字符串
                    List<StudentBean> beanList = studentsByName.stream().map(line -> {
                        String[] fields = line.split(",");
                        return new StudentBean(Integer.parseInt(fields[0]), fields[1], Integer.parseInt(fields[2]), fields[3], fields[4], fields[5]);
                    }).collect(Collectors.toList());


                    String jsonString = JSON.toJSONString(beanList);

                    // 将结果发给客户端
                    outputStream.write((jsonString + "\n").getBytes());
                } else {
                    outputStream.write("ERROR\n".getBytes());
                }
            } else if (arr2[0].equals("ADD")) {
                String studentInfo = arr2[1];
                String[] fields = studentInfo.split(",");
                StudentBean studentBean = new StudentBean(Integer.parseInt(fields[0]), fields[1], Integer.parseInt(fields[2]), fields[3], fields[4], fields[5]);
                dataManagerService.appendStudent(studentBean);

                outputStream.write("ok\n".getBytes());
            } else {
                outputStream.write("ERROR\n".getBytes());
            }

            outputStream.close();
            inputStream.close();
            socket.close();

        }


    }
}


